#include <iostream>
#include <thread>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <cstring>

using namespace std;

class FIFO
{
public:
    static void create_fifo(const string &filename)
    {
        if (mkfifo(filename.c_str(), IPC_CREAT | IPC_EXCL | 0655) < 0)
        {
            if (errno == EAGAIN)
            {
                mkfifo(filename.c_str(), 0);
            }
            else
            {
                perror("mkfifo error!");
                exit(1);
            }
        }
    }

    static int open_fifo(const string &filename)
    {
        int fd = open(filename.c_str(), O_RDWR);
        if (fd == -1)
        {
            perror("open file error!");
            exit(1);
        }

        return fd;
    }
};

class ReadFiFo1
{
public:
    static void read_data(int fd)
    {
        char buffer[1024];
        while (1)
        {
            memset(buffer, 0, sizeof(buffer));
            read(fd, buffer, sizeof(buffer - 1));
            cout << "read fifo1 = " << buffer << endl;
        }
    }
};

class ReadFiFo3
{
public:
    void operator()(int fd)
    {
        char buffer[1024];
        while (1)
        {
            memset(buffer, 0, sizeof(buffer));
            read(fd, buffer, sizeof(buffer - 1));
            cout << "read fifo3 = " << buffer << endl;
        }
    }
};

class ReadFiFo4
{
public:
    void read_data4(int fd)
    {
        char buffer[1024];
        while (1)
        {
            memset(buffer, 0, sizeof(buffer));
            read(fd, buffer, sizeof(buffer - 1));
            cout << "read fifo4 = " << buffer << endl;
        }
    }
};

class ReadFunction
{
public:
    static void run()
    {
        FIFO::create_fifo("/tmp/fifo1");
        FIFO::create_fifo("/tmp/fifo2");
        FIFO::create_fifo("/tmp/fifo3");
        FIFO::create_fifo("/tmp/fifo4");

        int fd;
        fd = FIFO::open_fifo("/tmp/fifo1");
        thread t1(ReadFiFo1::read_data, fd);

        fd = FIFO::open_fifo("/tmp/fifo2");
        auto read_data2 = [=]()
        {
            char buffer[1024];
            while (1)
            {
                memset(buffer, 0, sizeof(buffer));
                read(fd, buffer, sizeof(buffer - 1));
                cout << "read fifo2 = " << buffer << endl;
            }
        };
        thread t2(read_data2);

        fd = FIFO::open_fifo("/tmp/fifo3");
        ReadFiFo3 read_data3;
        thread t3(read_data3, fd);

        fd = FIFO::open_fifo("/tmp/fifo4");
        ReadFiFo4 f;
        thread t4(&ReadFiFo4::read_data4, f, fd);
    }
};

//创建两个线程，1个写线程hello world \n  2：hhhhh  wwww \n
//类成员函数
class write0
{
    public:
        static void write1()
        {

        }
        static void write2()
        {

        }
};

int main(int argc, char **argv)
{
    //ReadFunction::run();
    // FIFO::create_fifo("f.txt");
    // int fd=FIFO::open_fifo("f.txt");
    // thread t1();
    // pause();

    return 0;
}